package debtbundler.domain.bll.solver;

import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

import debtbundler.domain.entity.Debt;
import debtbundler.domain.entity.Person;
import debtbundler.domain.entity.impl.EntityManager;

/**
 * A debt solver that settles debts between debtors and creditors their input order
 * without trying to minimize the number of debts.   
 * 
 * @author Anssi
 *
 */
public class SimpleSolver extends SolverSkeleton {
	private static Logger logger = Logger.getLogger(SimpleSolver.class.getName());
		
	/**
	 * Solves the debts between given persons.

	 * @param persons	persons whose debts to calculate
	 * @throws UnbalancedCostsException
	 * 	if the costs and incomes to the given persons are not balanced within accuracy of 0.005
	 */	
	public SimpleSolver(Collection<Person> persons) throws UnbalancedCostsException {
		solve(persons);
	}	

	@Override
	protected void calculateSolution() {		
		while (!(debtors.isEmpty() || creditors.isEmpty())) {
			logger.log(Level.FINER, "#Debtors: {0}, #creditors {1}", new Object[]{debtors.size(), creditors.size()});
			
			Person debtor = debtors.get(0); 
			double totalToPay = Math.abs(debtor.getBalance());
			Person creditor = creditors.get(0);
			double totalToGet = Math.abs(creditor.getBalance());
			
			logger.log(Level.FINER, "Matching debtor {0} ({1}) and creditor {2} ({3})", new Object[]{debtor, debtor.getBalance(), debtor, creditor.getBalance()});
			
			Debt debt = EntityManager.createDebt(debtor, creditor);
			if (totalToGet > totalToPay) {
				debt.setValue(totalToPay);
				debtors.remove(debtor);
			} else if (totalToGet < totalToPay) {
				debt.setValue(totalToGet);
				creditors.remove(creditor);
			} else {
				debt.setValue(totalToGet);
				debtors.remove(debtor);
				creditors.remove(creditor);
			}
			
			debts.add(debt);
			logger.log(Level.FINER, "Created debt {0}", debt);
		}
		
		logger.log(Level.FINER, "Debts solved");
	}
	
	
}
